package com.qf.common.pay.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradeCloseModel;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeCloseRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeCloseResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import com.qf.common.pay.config.AliPayProperties;
import com.qf.common.pay.dto.PayDTO;
import com.qf.common.pay.param.FinishPayParam;
import com.qf.common.pay.param.RefundParam;
import com.qf.common.pay.service.PayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.function.Consumer;

/**
 * @Classname AliPayServiceImpl
 * @Description TODO
 * @Date 2025-06-03 11:38
 * @Created by 老任与码
 */
@Slf4j
@Service
public class AliPayServiceImpl implements PayService {

    @Resource
    private AliPayProperties aliPayProperties;

    @Resource
    private AlipayClient alipayClient;

    @Override
    public String createPay(PayDTO payDTO) {
        log.info("开始调用支付宝支付接口");
        // 使用的支付方式不同，请求对象和Model也都不同
        AlipayTradeWapPayRequest alipay_request = new AlipayTradeWapPayRequest();
        // 封装请求支付信息
        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        // 设置支付产品的编码
        model.setProductCode("QUICK_WAP_WAY");
        //订单编号，不可重复
        model.setOutTradeNo(payDTO.getOrderNo());
        //订单名称,拼接用户编码
        model.setSubject("支付宝支付订单");
        //订单金额
        model.setTotalAmount(payDTO.getAmount().setScale(2, BigDecimal.ROUND_HALF_UP).toString());
        // 设置中途退出的跳转路径
        model.setQuitUrl(aliPayProperties.getQuitUrl());
        alipay_request.setBizModel(model);
        // 异步通知地址
        alipay_request.setNotifyUrl(aliPayProperties.getNotifyUrl());
        // 支付成功后跳转的地址
        alipay_request.setReturnUrl(aliPayProperties.getReturnUrl());

        // 执行支付的返回值
        String result = "";
        try {
            // 调用SDK生成订单
            AlipayTradeWapPayResponse response = alipayClient.pageExecute(alipay_request);
            result = response.getBody();
            log.info("调用支付宝支付接口返回值result:" + result);
            // 返回form表单的字符串
            return result;
        } catch (AlipayApiException e) {
            throw new RuntimeException("支付宝支付失败");
        }
    }

    @Override
    public void notify(HttpServletRequest request, HttpServletResponse response, Consumer<FinishPayParam> consumer) {
        log.info("进入支付宝异步回调方法");
        Map<String, String> map = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            map.put(name, valueStr);
        }
        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表
        //支付宝交易号
        String tradeNo = request.getParameter("trade_no");
        //获取总金额
        String totalFee = request.getParameter("total_amount");
        //获取订单号
        String orderNo = request.getParameter("out_trade_no");
        //获取交易状态
        String tradeStatus = request.getParameter("trade_status");
        log.info("支付宝异步回调交易状态trade_status：" + tradeStatus);

        //验证签名
        boolean signVerified = false;
        try {
            signVerified = AlipaySignature.rsaCheckV1(map,
                    aliPayProperties.getAlipayPublicKey(),
                    aliPayProperties.getCharset(),
                    aliPayProperties.getSignType());
            log.info("支付宝异步回调方法：验签结果" + signVerified);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return;
        }
        if (signVerified) {
            try {
                if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISH".equals(tradeStatus)) {
                    // BigDecimal totalFees = new BigDecimal(totalFee);
                    // 支付后业务处理
                    FinishPayParam param = new FinishPayParam();
                    param.setOutTradeNo(orderNo);
                    param.setTradeNo(tradeNo);
                    consumer.accept(param);
                } else {
                    return;
                }
                log.info("支付成功异步回调success:" + orderNo);
                //该语句不要修改或删除
                response.getOutputStream().println("success");
                response.getOutputStream().close();
            } catch (Exception e) {
                log.info("支付成功异步回调异常:" + e.getMessage());
            }
        } else {
            log.info("支付成功异步回调fail");
            try {
                response.getOutputStream().println("fail");
                response.getOutputStream().close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return;
    }

    @Override
    public String payStatus(String orderNo) {
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();
        model.setOutTradeNo(orderNo);
        request.setBizModel(model);
        AlipayTradeQueryResponse response = null;
        try {
            response = alipayClient.execute(request);
            System.out.println(response.getBody());
            if (response.isSuccess()) {
                System.out.println("调用成功");
                String tradeStatus = response.getTradeStatus();// WAIT_BUYER_PAY
                if (tradeStatus.equals("WAIT_BUYER_PAY")) {
                    throw new RuntimeException("等待支付");// 还需要返回特定的异常编码
                }
            } else {
                throw new RuntimeException("调用异常");
            }

        } catch (AlipayApiException e) {
            e.printStackTrace();
            throw new RuntimeException("查询支付状态异常");
        }
        return response.getTradeNo();
    }

    @Override
    public void closePay(String orderNo) {
        AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
        AlipayTradeCloseModel model = new AlipayTradeCloseModel();
        model.setOutTradeNo(orderNo); // 商户订单号
        request.setBizModel(model);
        AlipayTradeCloseResponse response = null;
        try {
            response = alipayClient.execute(request);
            System.out.println(response.getBody());
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
    }

    /**
     * 进行验证签名
     *
     * @param request
     * @param response
     */
    @Override
    public void returnNotify(HttpServletRequest request, HttpServletResponse response,Consumer<FinishPayParam> consumer) {
        log.info("支付宝同步回调方法");
        Map<String, String> map = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            map.put(name, valueStr);
        }
        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
        String trade_no = request.getParameter("trade_no");             //支付宝交易号
        String order_no = request.getParameter("out_trade_no");         //获取订单号
        String total_fee = request.getParameter("total_amount");           //获取总金额
//		String userId = feignAlipayService.getUserById(order_no);
        //验证签名
        boolean signVerified = false;
        try {
            signVerified = AlipaySignature.rsaCheckV1(map,
                    aliPayProperties.getAlipayPublicKey(),
                    aliPayProperties.getCharset(),
                    aliPayProperties.getSignType());
            log.info("支付宝同步回调方法:验签成功");
        } catch (AlipayApiException e) {
            e.printStackTrace();
            throw new RuntimeException("验签失败");
        }
        // 如果验证通过
        if (signVerified) {
            // 修改相关数据
            log.info("支付宝同步调用支付成功");
            FinishPayParam param = new FinishPayParam();
            param.setOutTradeNo(order_no);
            param.setTradeNo(trade_no);
            consumer.accept(param);
        } else {
            log.info("支付宝支付异常");
            throw new RuntimeException("支付宝支付异常");
        }
    }

    @Override
    public String refundOrder(RefundParam refundParam) {
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();

        // 设置业务订单号
        model.setOutTradeNo(refundParam.getOrderNo());

        // 设置退款金额
        model.setRefundAmount(refundParam.getRefundAmount().setScale(2, BigDecimal.ROUND_HALF_UP).toString());

        // 设置其他退款参数，如商品信息、分账信息等（根据需求填写）
        // ...

        request.setBizModel(model);

        try {
            AlipayTradeRefundResponse response = alipayClient.execute(request);
            System.out.println(response.getBody());

            if (response.isSuccess()) {
                System.out.println("调用成功");
                return response.getTradeNo(); // 返回支付宝交易号
            } else {
                System.out.println("调用失败");
                return "调用失败";
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            throw new RuntimeException("支付宝退款失败");
        }
    }


}
